package com.sciencep.pro.admin.system.controller;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sciencep.pro.admin.system.common.util.UserUtil;
import com.sciencep.pro.common.config.Constant;
import com.sciencep.pro.common.domain.OscaConstant;
import com.sciencep.pro.common.domain.QueryRequest;
import com.sciencep.pro.common.domain.ResponseResult;
import com.sciencep.pro.common.exception.CustomException;
import com.sciencep.pro.common.utils.SortUtil;
import com.sciencep.pro.core.domain.dto.home.ParticipatedInInfoVO;
import com.sciencep.pro.core.domain.dto.project.*;
import com.sciencep.pro.core.domain.dto.user.UserDetail;
import com.sciencep.pro.core.domain.entity.*;
import com.sciencep.pro.core.service.*;
import com.taobao.api.ApiException;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

@RequestMapping("/project")
@RestController
@Slf4j
public class ProjectController {

    @Autowired
    IProNodeService proNodeService;

    @Autowired
    IProTypeService typeService;

    @Autowired
    IBranchService branchService;

    @Autowired
    IDataInfoService dataInfoService;

    @Autowired
    IProBaseInfoService proBaseInfoService;

    @Autowired
    IProRoleService proRoleService;

    @Autowired
    IProAssignmentService proAssignmentService;

    @Autowired
    DingDingService dingDingService;

    @Autowired
    ITokenInfoService tokenInfoService;

    @Autowired
    IProDataService proDataService;

    @Autowired
    private UserUtil userUtil;


    @GetMapping("/base/data")
    @ApiOperation(value = "新建项目初始化", notes = "新建项目初始化")
    public ResponseResult<Object> getProjectBaseData() {


        ProStartInfoTO proStartInfoTO = new ProStartInfoTO();
        proStartInfoTO.setProTypeTOList(typeService.getTypeList());
        proStartInfoTO.setProNodeTOList(proNodeService.getProNodeList(null));
        proStartInfoTO.setBranchTOList(branchService.getBranchList());
        proStartInfoTO.setBranchContactTOList(branchService.getBranchContactTO(null));
        proStartInfoTO.setDataInfoTOList(dataInfoService.getDataInfoList());


        return new ResponseResult<>().success(proStartInfoTO);
    }

    @GetMapping("/type/list")
    @ApiOperation(value = "查询项目类型", notes = "查询项目类型")
    public ResponseResult<Object> getProjectTypes() {

        return new ResponseResult<>().success(typeService.getTypeList());


    }

    @GetMapping("/node/list")
    @ApiOperation(value = "查询项目节点", notes = "查询项目节点")
    public ResponseResult<Object> getProjectNodes(@RequestParam String typeId) {

        return new ResponseResult<>().success(proNodeService.getProNodeList(typeId));

    }

    @GetMapping("/branch/list")
    @ApiOperation(value = "查询分社节点", notes = "查询分社节点")
    public ResponseResult<Object> getBranches() {
        return new ResponseResult<>().success(branchService.getBranchList());
    }

    @PostMapping("/branch/contact")
    @ApiOperation(value = "查询分社对接人", notes = "查询分社对接人")
    public ResponseResult<Object> getBranchContact(@RequestBody  List<String> branchIds) {
        return new ResponseResult<>().success(branchService.getBranchContactTO(branchIds));
    }

    @GetMapping("/data/list")
    @ApiOperation(value = "查询项目资料", notes = "查询项目资料")
    public ResponseResult<Object> getDataList() {

        return new ResponseResult<>().success(dataInfoService.getDataInfoList());
    }

    @GetMapping("/data/page")
    @ApiOperation(value = "查询项目资料分页", notes = "查询项目资料分页")
    public ResponseResult<Object> getDataPage(QueryRequest queryRequest) {

        Page<DataInfo> page = new Page<>();
        page.setCurrent(queryRequest.getPageNum()).setSize(queryRequest.getPageSize());
        return new ResponseResult<>().success(dataInfoService.page(page,new LambdaQueryWrapper<DataInfo>().orderByDesc(DataInfo::getCreateDate)));
    }

    @PostMapping("/data")
    @ApiOperation(value = "新增项目资料")
    public ResponseResult<Object> add(@RequestBody DataInfo dataInfo) {
        if (dataInfoService.count(new LambdaQueryWrapper<DataInfo>().eq(DataInfo::getDataName, dataInfo.getDataName())) > 0) {
            return new ResponseResult<>().failure(Constant.ErrorCode.SYSTEM_ERROR, "重复的项目资料名");
        }
        dataInfoService.save(dataInfo);
        return new ResponseResult<>().success();
    }

    @PutMapping("/data")
    @ApiOperation(value = "修改项目资料")
    public ResponseResult<Object> update(@RequestBody DataInfo dataInfo) {
        if (dataInfoService.count(new LambdaQueryWrapper<DataInfo>().eq(DataInfo::getDataName, dataInfo.getDataName())) > 0) {
            return new ResponseResult<>().failure(Constant.ErrorCode.SYSTEM_ERROR, "重复的项目资料名");
        }
        dataInfoService.updateById(dataInfo);
        return new ResponseResult<>().success();
    }

    @DeleteMapping("/data")
    @ApiOperation(value = "删除项目资料")
    public ResponseResult<Object> delete(@RequestParam("id") String id) {
        if (proDataService.count(new LambdaQueryWrapper<ProData>().eq(ProData::getProDataId, id)) > 0) {
            return new ResponseResult<>().failure(Constant.ErrorCode.SYSTEM_ERROR, "该资料在使用中,不可删除");
        }
        dataInfoService.removeById(id);
        return new ResponseResult<>().success();
    }


    @PostMapping("/save")
    @ApiOperation(value = "项目新增保存", notes = "新增项目保存")
    public ResponseResult<Object> saveProject(@Valid @RequestBody ProjectTO projectTO) throws CustomException {

        UserDetail userDetail = userUtil.getCurrentUserDetail();
        return proBaseInfoService.saveProject(projectTO, userDetail);
    }

    @PostMapping("/save/dingding")
    @ApiOperation(value = "提交到钉钉", notes = "提交到钉钉")
    public ResponseResult<Object> saveToDingDing(@RequestBody ProjectTO projectTO) throws CustomException, ApiException {

        UserDetail userDetail = userUtil.getCurrentUserDetail();
        proBaseInfoService.saveToDingDing(projectTO, userDetail);
        return new ResponseResult<>().success();
    }

    @PostMapping("/update")
    @ApiOperation(value = "项目更新", notes = "项目更新")
    public ResponseResult<Object> updateProject(@Valid @RequestBody ProjectTO projectTO) throws CustomException {

        UserDetail userDetail = userUtil.getCurrentUserDetail();
        proBaseInfoService.updateProject(projectTO, userDetail);
        return new ResponseResult<>().success();
    }

    @PostMapping("/change")
    @ApiOperation(value = "项目变更", notes = "项目变更")
    public ResponseResult<Object> changeProject(@RequestBody ProjectChangeTO projectChangeTO) throws CustomException {

        UserDetail userDetail = userUtil.getCurrentUserDetail();
        String changeNo = proBaseInfoService.changeProject(projectChangeTO, userDetail);

        return new ResponseResult<>().success(changeNo);
    }

    @GetMapping(value = "/editProjectInit")
    @ApiOperation(value = "查询项目基本信息")
    public ResponseResult<ProjectTO> editProjectInit(ProBaseInfo proBaseInfo) throws ParseException {
        return new ResponseResult<ProjectTO>().success(proBaseInfoService.editProjectInit(proBaseInfo));
    }

    @GetMapping(value = "/getProjectInfo")
    @ApiOperation(value = "查询项目详细信息")
    public ResponseResult<ProjectTO> getProjectInfo(ProBaseInfo proBaseInfo) throws ParseException {
        return new ResponseResult<ProjectTO>().success(proBaseInfoService.getProjectInfo(proBaseInfo));
    }

    @GetMapping(value = "/getProjectInfo/data")
    @ApiOperation(value = "查询项目资料")
    public ResponseResult<List<ProDataTO>> getProjectInfoData(String proId) {
        return new ResponseResult<List<ProDataTO>>().success(proBaseInfoService.getProjectInfoData(proId));
    }


    @PostMapping(value = "/audit")
    @ApiOperation("项目变更审批结果")
    public ResponseResult<Object> auditChange(@RequestBody @Valid ProChangeAuditTO proChangeAuditTO) throws CustomException {

        UserDetail currentUser = userUtil.getCurrentUserDetail();
        proBaseInfoService.auditChange(proChangeAuditTO, currentUser);

        return new ResponseResult<>().success();
    }

    @GetMapping(value = "/getProjectCode")
    @ApiOperation(value = "获取项目编号")
    public ResponseResult<ProjectTO> getProjectCode(ProBaseInfo proBaseInfo) {
        ProjectTO projectTO = proBaseInfoService.getProjectCode(proBaseInfo);
        if (projectTO != null) {
            return new ResponseResult<ProjectTO>().success(projectTO);
        } else {
            return new ResponseResult<ProjectTO>().failure();
        }
    }


    @GetMapping("/getInprocessingProList")
    @ApiOperation(value = "查询所有进行中的项目")
    public ResponseResult<Object> getInprocessingProList() throws CustomException {


        String userId = userUtil.getCurrentUserDetail().getUserId();

        return new ResponseResult<>().success(proBaseInfoService.getInprocessingProList(userId));
    }

    @GetMapping("/getAllProList")
    @ApiOperation(value = "查询所有进行中的项目")
    public ResponseResult<Object> getAllProList() {

        return new ResponseResult<>().success(proBaseInfoService.getAll());
    }

    @GetMapping("/getProAndBakList")
    @ApiOperation(value = "查询所有进行中的项目")
    public ResponseResult<Object> getProAndBakList() {

        return new ResponseResult<>().success(proBaseInfoService.getProAndBakList());
    }

    @GetMapping("/MandayStatisticsChart")
    @ApiOperation(value = "项目人天图")
    public ResponseResult<Object> getMandayStatisticsChart(@RequestParam("proId") String proId, @RequestParam("proNo") String proNo, Integer type) {

        return new ResponseResult<>().success(proBaseInfoService.getMandayStatisticsChart(proId, proNo, type));
    }

    @GetMapping("/BurndownChartTOChart")
    @ApiOperation(value = "燃尽图")
    public ResponseResult<Object> getBurndownChartTO(@RequestParam("proId") String proId, @RequestParam("proNo") String proNo) {

        return new ResponseResult<>().success(proBaseInfoService.getBurndownChartTO(proId, proNo));
    }

    @GetMapping("/projectWorkloadTrendChart")
    @ApiOperation(value = "工作量趋势图")
    public ResponseResult<Object> getProjectWorkloadTrendChart(@RequestParam("proId") String proId, @RequestParam("proNo") String proNo) {


        return new ResponseResult<>().success(proBaseInfoService.getWorkloadTrendChartTOList(proId, proNo));
    }

    @GetMapping("/project/changeDetail")
    @ApiOperation(value = "查询项目变更明细")
    public ResponseResult<ProChangeDetailTO> getChangeDetail(@RequestParam String proId, @RequestParam String proNodeId) {


        return new ResponseResult<ProChangeDetailTO>().success(proBaseInfoService.getProChangeDetailTO(proId, proNodeId));
    }

    @GetMapping("/proRole/list")
    @ApiOperation(value = "项目角色列表")
    public ResponseResult<Object> getProRoleList() {

        return new ResponseResult<>().success(proRoleService.list(new LambdaQueryWrapper<ProRole>().eq(ProRole::getIsDel, Constant.IsDelete.NO)));
    }

    @GetMapping("/proRole/page")
    @ApiOperation(value = "项目角色分页")
    public ResponseResult<Object> getProRolePage(QueryRequest queryRequest) {

        Page<ProRole> page = new Page<>();
        SortUtil.handlePageSort(queryRequest, page, "id", OscaConstant.ORDER_DESC, false);

        return new ResponseResult<>().success(proRoleService.page(page, new LambdaQueryWrapper<ProRole>().eq(ProRole::getIsDel, Constant.IsDelete.NO)));
    }

    @PostMapping("/proRole")
    @ApiOperation(value = "新增项目角色")
    public ResponseResult<Object> saveProRole(@Valid @RequestBody ProRole proRole) {

        if (StringUtils.isBlank(proRole.getRoleName())) {
            return new ResponseResult<>().failure(Constant.ErrorCode.SYSTEM_ERROR, "项目角色不能为空");
        }
        if (proRoleService.count(new LambdaQueryWrapper<ProRole>().eq(ProRole::getRoleName, proRole.getRoleName()).eq(ProRole::getIsDel, Constant.IsDelete.NO)) > 0) {
            return new ResponseResult<>().failure(Constant.ErrorCode.SYSTEM_ERROR, "项目角色重复");
        }
        proRole.setIsDel(Constant.IsDelete.NO);
        proRoleService.save(proRole);
        return new ResponseResult<>().success();
    }

    @DeleteMapping("/proRole")
    @ApiOperation("删除角色")
    public ResponseResult<Object> deleteRole(Long roleId) {

        if (proAssignmentService.count(new LambdaQueryWrapper<ProAssignment>()
                .eq(ProAssignment::getProroleId, roleId)) > 0) {
            return new ResponseResult<>().failure(Constant.ErrorCode.SYSTEM_ERROR, "该角色在使用中,不可删除");
        }
        proRoleService.update(new UpdateWrapper<ProRole>().eq("id", roleId).set("isDel", Constant.IsDelete.YES));
        return new ResponseResult<>().success();
    }

    @GetMapping(value = "/getWorkDay")
    @ApiOperation("根据时间区间获取工作日")
    public ResponseResult<Object> getWorkDay(@RequestParam String beginDate, @RequestParam String endDate) throws ParseException {
        return new ResponseResult<>().success(proBaseInfoService.getWorkDay(beginDate, endDate));
    }

    @PostMapping("/save/dingding/change")
    @ApiOperation(value = "项目变更提交到钉钉", notes = "项目变更提交到钉钉")
    public ResponseResult<Object> saveToDingDing(@RequestBody ProjectChangeTO projectChangeTO) throws CustomException, ApiException {

        TokenInfo tokenInfo = tokenInfoService.getOne(new LambdaQueryWrapper<TokenInfo>().eq(TokenInfo::getIsDel, Constant.IsDelete.NO).eq(TokenInfo::getType,1));
        String token = dingDingService.getAccessToken(tokenInfo.getAppKey(), tokenInfo.getAppSecret());
        ProjectUpdateTO projectUpdateTO = new ProjectUpdateTO();
        projectUpdateTO.setChangeNo(projectChangeTO.getChangeNo());
        ProBaseInfo proBaseInfo = proBaseInfoService.getById(projectChangeTO.getProId());

        projectUpdateTO.setProDateChange("变更前：" + changeToString(projectChangeTO.getOldProStartDate()) + " ~ " + changeToString(projectChangeTO.getOldProEndDate())
                + "； 变更后： " + changeToString(projectChangeTO.getNewProStartDate()) + " ~ " + changeToString(projectChangeTO.getNewProEndDate()));
        projectUpdateTO.setNodeDateChange("变更前： " + changeToString(projectChangeTO.getOldNodeStartDate()) + " ~ " + changeToString(projectChangeTO.getOldNodeEndDate())
                + "；变更后：" + changeToString(projectChangeTO.getNewNodeStartDate()) + " ~ " + changeToString(projectChangeTO.getNewNodeEndDate()));
        projectUpdateTO.setChangeDesc(projectChangeTO.getProName() + "---" + projectChangeTO.getNodeName());

        StringBuilder newUserString = new StringBuilder();
        for (AddUserTO addUserTO : projectChangeTO.getAddUserTOList()) {
            newUserString.append(addUserTO.getUserName()).append(" 投入方式:").append(addUserTO.getInputTypeName()).append(" 累计投入:").append(addUserTO.getInputDaily()).append("  投入日期:").append(changeToDate(addUserTO.getInputStart())).append(" ~ ").append(changeToDate(addUserTO.getInputEnd())).append("; ");
        }
        StringBuilder updateString = new StringBuilder();
        for (UpdateUserTO updateUserTO : projectChangeTO.getUpdateUserTOList()) {
            updateString.append(updateUserTO.getUserName()).append(" 投入方式:").append(updateUserTO.getInputTypeNameOld()).append( "->").append(updateUserTO.getInputTypeNameNew()).append(" 累计投入：").append(updateUserTO.getInputDailyOld()).append("->").append(updateUserTO.getInputDailyNew()).append("  投入日期:").append(changeToDate(updateUserTO.getInputStartNew())).append(" ~ " ).append(changeToDate(updateUserTO.getInputEndNew())).append("; ");
        }
        projectUpdateTO.setUpdateMember(updateString.toString());
        projectUpdateTO.setNewMember(newUserString.toString());
        projectUpdateTO.setDeptId(proBaseInfo.getDeptId());
        dingDingService.createProjectUpdateProcessInstance(projectUpdateTO, token, userUtil.getCurrentUserDetail().getUserId());

        return new ResponseResult<>().success();
    }

    @PostMapping(value = "/finishProject")
    @ApiOperation("项目状态更改成已完成")
    public ResponseResult<Object> finishProject(@RequestBody ProBaseInfo proBaseInfo) {
        return new ResponseResult<>().success(proBaseInfoService.finishProject(proBaseInfo));
    }

    @PostMapping(value = "/updateContractCode")
    @ApiOperation("修改合同编号")
    public ResponseResult<Object> updateContractCode(@RequestBody ProBaseInfo proBaseInfo){
        return new ResponseResult<>().success(proBaseInfoService.updateContractCode(proBaseInfo));
    }

    @GetMapping(value = "/getMyProject")
    @ApiOperation("获取自己创建的项目")
    public ResponseResult<Page<ParticipatedInInfoVO>> getMyProject(QueryRequest queryRequest) throws CustomException {
        return new ResponseResult<Page<ParticipatedInInfoVO>>().success(proBaseInfoService.getMyProject(userUtil.getCurrentUserDetail().getUserId(),queryRequest));
    }

    @PostMapping(value = "/deleteProjectById")
    @ApiOperation("删除项目(逻辑删除)")
    public ResponseResult<Object> deleteProjectById(@RequestBody ProBaseInfo proBaseInfo){
        proBaseInfo.setIsDel(Constant.IsDelete.YES);
        return new ResponseResult<>().success(proBaseInfoService.updateById(proBaseInfo));
    }


    private String changeToString(Date date) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        if (date == null) {
            return "";
        }
        return sdf.format(date);
    }

    private String changeToDate(String s) {

        if (StringUtils.isNotBlank(s) && s.length() >= 10) {
            return s.substring(0, 10);
        }
        return s;
    }
}
